package com.cloud.point.concurrent.juc;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import lombok.extern.slf4j.Slf4j;

/**
 * TestCountdownLatch
 *
 * @author 24373
 * @version 1.0
 * @date 2024-06-22 16:34
 */
@Slf4j
public class TestCountdownLatch {

    public static void main(String[] args) {
        //test();
        test2();
    }

    /**
     * 模拟多个线程并发执行
     */
    private static void test2() {
        ExecutorService pool = Executors.newFixedThreadPool(11);
        CountDownLatch latch = new CountDownLatch(10);
        Random random = new Random();
        String[] arr = new String[10];
        for (int j = 0; j < 10; j++) {
            final int k = j;
            pool.submit(() -> {
                for (int i = 0; i <= 100; i++) {
                    arr[k] = i + "%";
                    try {
                        Thread.sleep(random.nextInt(100));
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.print("\r" + Arrays.toString(arr));
                }
                latch.countDown();
            });
        }
        pool.submit(() -> {
            try {
                latch.await();
                log.info("执行结束");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        pool.shutdown();

    }

    /**
     * 基本使用
     */
    private static void test() {
        ExecutorService pool = Executors.newFixedThreadPool(3);
        CountDownLatch count = new CountDownLatch(2);
        pool.execute(() -> {
            log.info("{}running", Thread.currentThread().getName());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            count.countDown();
        });
        pool.execute(() -> {
            log.info("{}running", Thread.currentThread().getName());
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            count.countDown();
        });
        pool.execute(() -> {
            log.info("{} latch running", Thread.currentThread().getName());
            try {
                count.await();
                log.info("{} latch end", Thread.currentThread().getName());
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        pool.shutdown();
    }

}
